home *** CD-ROM | disk | FTP | other *** search
- From: Torsten Scherer <itschere@techfak.uni-bielefeld.de>
- Subject: strange Fselect/Finstat behaviour...
- Date: Mon, 3 Jan 94 0:29:54 +0100
-
- Hope anyone out there has had a good start into the new year...
-
- Mine was a bit nervous, because while I was trying to get my head back
- into a more comfortable state after the New Years Eve party it was once
- again hit by a severe programming problem. Obviously it wasn't the perfect
- time for this problem to arise, so I didn't really manage to track it down.
-
- I was trying to improve my `talk' program, which puts the current device
- into RAW mode to be able to read keys like ^C for example, which then get
- sent through a pipe to inform the remote partner that a connection is to
- be shut down.
-
- Knowing that Fselect() only really works on pipes or the `real' console
- device, but not on other devices, I used Fselect(50, &rfd, 0L, 0L) to not
- spend too much time in a busy-poll loop and still be able to use it for
- tty input. Since the corresponding tty is in RAW mode, I'd expect it to
- give me a 0x03 from Fread() when ^C is pressed. Instead, the process got
- the SIGINT signal and was killed all the time.
-
- When trying not to use Fselect() at all for tty input, but just for pipe
- input with a timeout, and later manually check the tty with Finstat() I got
- the same result. Since a RAW Fread() will return for every char regardless
- how many you ordered, but not if there isn't one at all, I ran out of clues
- on how to check the tty input without blocking and changed my program to
- catch SIGINT instead of reading it from the tty so it now more or less
- does what I want.
-
- But the problem remains and if you'd like to check it, then run:
-
- /*
- * murphy on the road again...
- */
-
- #include <ioctl.h>
- #include <mintbind.h>
- #include <signal.h>
- #include <stdio.h>
-
- void catch(long sig)
- {
- printf("hit by SIGINT\r\n");
- }
-
- void main()
- {
- struct sgttyb tty;
- long rfd;
- char c;
-
- Psignal(SIGINT, catch);
-
- ioctl(0, TIOCGETP, &tty);
- tty.sg_flags = RAW;
- ioctl(0, TIOCSETP, &tty);
-
- for (;;) {
- #if 1
- if (Finstat(0)) {
- #else
- rfd = 1;
- (void)Fselect(50, &rfd, 0L, 0L);
- if (rfd) {
- #endif
- Fread(0, 1L, &c);
- printf("key = %i\r\n", c);
- }
- }
- }
-
- If you do so, you'll have to face the strange fact that the _first_ ^C will
- raise the signal, whereas every following one will read as 0x03 from the
- Fread() call.
-
- A pure:
-
- for (;;) {
- Fread(0, 1L, &c);
- printf("key = %i\r\n", c);
- }
-
- won't do this but report 0x03 for every ^C instead, just like you and I
- might have expected it, but gives you no possibility to do other things
- if there isn't any input at all.
-
- All this happenes with MiNT 1.09 plus no patches except the nalloc stuff
- and my own ones dealing with the biosfs and the sticky bit AND the original
- MiNT 1.04. Allthough I may have very well missed some patches cause I don't
- save them all if I think I don't need them, but prefer to wait for the next
- official update instead, I consider this being a `new' problem.
-
- So has anyone got the faintest idea what this is meant to say me? Looks
- like the combination of dev->ioctl(FIONREAD) and/or dev->select affects the
- process' signal stuff in a very bad way, but before I try to get through
- this I'd like to have it discussed here.
-
- so long,
- TeSche
- --
- PS: If the above written looks weird, then that's probably because it _is_.
- WhoDunnIt: Torsten Scherer (Schiller, Tesche, ...)
- Where: Faculty of Technology, University of Bielefeld, Germany
- EMail: itschere@techfak.uni-bielefeld.de / tesche@hrz.uni-bielefeld.de
-